package com.zyw.codegen.xml;

import com.zyw.orm.support.page.Page;
import org.mybatis.generator.api.IntrospectedColumn;
import org.mybatis.generator.api.dom.xml.Attribute;
import org.mybatis.generator.api.dom.xml.TextElement;
import org.mybatis.generator.api.dom.xml.XmlElement;
import org.mybatis.generator.codegen.mybatis3.ListUtilities;
import org.mybatis.generator.codegen.mybatis3.MyBatis3FormattingUtilities;
import org.mybatis.generator.codegen.mybatis3.xmlmapper.XMLMapperGenerator;
import org.mybatis.generator.codegen.mybatis3.xmlmapper.elements.AbstractXmlElementGenerator;

import static org.mybatis.generator.internal.util.StringUtility.stringHasValue;

/**
 * @author zhangyw
 * @date 2017/3/14 17:22
 */
public class CustomXmlMapperGenerator extends XMLMapperGenerator {

    public CustomXmlMapperGenerator() {
        super();
    }

    @Override
    protected XmlElement getSqlMapElement() {
        XmlElement answer = super.getSqlMapElement();

        addFindByPageElement(answer);

        return answer;
    }

    protected void addFindByPageElement(XmlElement parentElement) {
        AbstractXmlElementGenerator elementGenerator = new AbstractXmlElementGenerator() {
            @Override
            public void addElements(XmlElement parentElement) {
                XmlElement answer = new XmlElement("select"); //$NON-NLS-1$

                answer.addAttribute(new Attribute(
                        "id", "findByPage")); //$NON-NLS-1$
                if (introspectedTable.getRules().generateResultMapWithBLOBs()) {
                    answer.addAttribute(new Attribute("resultMap", //$NON-NLS-1$
                            introspectedTable.getResultMapWithBLOBsId()));
                } else {
                    answer.addAttribute(new Attribute("resultMap", //$NON-NLS-1$
                            introspectedTable.getBaseResultMapId()));
                }

                String parameterType;
                // PK fields are in the base class. If more than on PK
                // field, then they are coming in a map.
                parameterType = Page.class.getName();

                answer.addAttribute(new Attribute("parameterType", parameterType));

                context.getCommentGenerator().addComment(answer);

                StringBuilder sb = new StringBuilder();
                sb.append("select "); //$NON-NLS-1$

                if (stringHasValue(introspectedTable
                        .getSelectByPrimaryKeyQueryId())) {
                    sb.append('\'');
                    sb.append(introspectedTable.getSelectByPrimaryKeyQueryId());
                    sb.append("' as QUERYID,"); //$NON-NLS-1$
                }
                answer.addElement(new TextElement(sb.toString()));
                answer.addElement(getBaseColumnListElement());
                if (introspectedTable.hasBLOBColumns()) {
                    answer.addElement(new TextElement(",")); //$NON-NLS-1$
                    answer.addElement(getBlobColumnListElement());
                }

                sb.setLength(0);
                sb.append("from "); //$NON-NLS-1$
                sb.append(introspectedTable
                        .getAliasedFullyQualifiedTableNameAtRuntime());
                answer.addElement(new TextElement(sb.toString()));

                XmlElement whereElement = new XmlElement("where");
                for (IntrospectedColumn introspectedColumn : ListUtilities.removeGeneratedAlwaysColumns(introspectedTable.getAllColumns())) {
                    XmlElement isNotNullElement = new XmlElement("if"); //$NON-NLS-1$
                    sb.setLength(0);
                    sb.append(introspectedColumn.getJavaProperty("paramBean."));
                    sb.append(" != null"); //$NON-NLS-1$
                    isNotNullElement.addAttribute(new Attribute("test", sb.toString())); //$NON-NLS-1$

                    sb.setLength(0);
                    sb.append(" and ");
                    sb.append(MyBatis3FormattingUtilities
                            .getEscapedColumnName(introspectedColumn));
                    sb.append(" = "); //$NON-NLS-1$
                    sb.append(MyBatis3FormattingUtilities
                            .getParameterClause(introspectedColumn, "paramBean."));
                    isNotNullElement.addElement(new TextElement(sb.toString()));
                    whereElement.addElement(isNotNullElement);
                }

                answer.addElement(whereElement);

                if (context.getPlugins()
                        .sqlMapSelectByPrimaryKeyElementGenerated(answer,
                                introspectedTable)) {
                    parentElement.addElement(answer);
                }
            }
        };
        initializeAndExecuteGenerator(elementGenerator, parentElement);
    }
}
